package com.itkf.core.executor;

import com.itkf.common.StrategyModel.StrategyChoose;
import com.itkf.core.rejectHandle.RejectHandle;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

@Component
@Slf4j
@Getter
public class DtpExecutor extends ThreadPoolExecutor {
    /**
     * 线程池名称
     */
    private String threadPoolName;
    /**
     * 拒绝策略数
     */
    private final AtomicLong rejectedCount = new AtomicLong();
    /**
     * 是否强制关闭线程池
     */
    private boolean waitTime;
    /**
     * 阻塞队列
     */
    private VariableQueue queue;
    /**
     * 拒绝策略
     */
    private RejectedExecutionHandler rejectedExecutionHandler;


    public DtpExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), new AbortPolicy());
    }

    public DtpExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, new AbortPolicy());
    }

    public DtpExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler);
    }

    public DtpExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        this.queue = new VariableQueue(workQueue);
    }


    @Override
    public void execute(Runnable command) {
        super.execute(command);
    }

    public void setRejectedHandler(String mark) {
        RejectHandle rawHandler = (RejectHandle) StrategyChoose.choose(mark);
        // 包装原生策略增加计数功能！！！  装饰器模式
        this.rejectedExecutionHandler = new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                rejectedCount.incrementAndGet();
                rawHandler.rejectedExecution(r, executor);
            }
        };
        super.setRejectedExecutionHandler(rejectedExecutionHandler);
    }

    public void setQueueCapacity(int capacity) {
        queue.setCapacity(capacity);
    }

    //修改容量非复合操作，直接使用volatile修饰
    public int getQueueCapacity() {
        return queue.getCapacity();
    }
}
